package com.bbva.itradecomex.bo.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import org.primefaces.component.menuitem.MenuItem;
import org.primefaces.component.submenu.Submenu;
import org.primefaces.model.DefaultMenuModel;
import org.primefaces.model.MenuModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.bbva.itradecomex.bo.iface.AccesoBO;
import com.bbva.itradecomex.dao.iface.AccesoDAO;
import com.bbva.itradecomex.domain.OpcionMenu;
import com.bbva.itradecomex.domain.PerfilOpcion;
import com.bbva.itradecomex.domain.Usuario;
import com.bbva.itradecomex.domain.UsuarioPerfil;
import com.bbva.itradecomex.util.Constantes;
import com.bbva.itradecomex.util.ITradexUtil;

@Service
public class AccesoBOImpl implements AccesoBO{

	@Autowired
	private AccesoDAO accesoDAO;
	
	@Override
	public Usuario consultaValidarRegistro(String codRegistro) throws Exception {
		return accesoDAO.consultaValidarRegistro(codRegistro);
	}
	
	@Override
	public MenuModel cargarMenuOpciones(Usuario usuario) throws Exception{
		List<UsuarioPerfil> listUserPerfil = accesoDAO.consultaUsuarioPerfil(usuario.getIdUsuario());
		
		List<String> listStringUserPerfil = new ArrayList<String>();
		for (UsuarioPerfil ob : listUserPerfil) {
			listStringUserPerfil.add(String.valueOf(ob.getIdPerfil()));
		}
		
		String arrayIdPerfil = ITradexUtil.getArrayCodigos(listStringUserPerfil, Constantes.COMA);
		List<PerfilOpcion> listPerfilOpcion = accesoDAO.consultaPerfilOpcion(arrayIdPerfil);
		
		//remove idOpcion repetidos
		for(int i=0; i<listPerfilOpcion.size(); i++){
			BigDecimal idOpcion = listPerfilOpcion.get(i).getIdOpcion();
			for(int j=(i+1); j<listPerfilOpcion.size(); j++){
				BigDecimal iOpcionT = listPerfilOpcion.get(j).getIdOpcion();
				if(idOpcion.compareTo(iOpcionT) == 0){
					listPerfilOpcion.remove(j);
					j--;
				}
			}
		}
		
		List<String> listStringPerfilOpcion = new ArrayList<String>();
		for (PerfilOpcion ob : listPerfilOpcion) {
			listStringPerfilOpcion.add(String.valueOf(ob.getIdOpcion()));
		}
		
		String arrayIdOpcion = ITradexUtil.getArrayCodigos(listStringPerfilOpcion, Constantes.COMA);
		List<OpcionMenu> listOpcion = accesoDAO.consultaOpcionMenu(arrayIdOpcion);
		
		return crearArbolMenuOpcion(listOpcion);
	}
	
	private MenuModel crearArbolMenuOpcion(List<OpcionMenu> list)
			throws Exception {
		MenuModel root = new DefaultMenuModel();
		if (list != null) {
			if (list.size() > 0) {
				for (int i = 0; i < list.size(); i++) {
					OpcionMenu opcionMenu = list.get(i);
					Submenu submenu = new Submenu();
					MenuItem menuItem = null;
					if (opcionMenu.getIdOpcionPadre() == null) {
						if(isUltimoHijo(list, opcionMenu)){
							menuItem = createMenuItem(opcionMenu);
						}else{
							submenu.setLabel(opcionMenu.getNomOpcion());
							adicionarMenu(opcionMenu, list, submenu);
						}
					} else {
						break;
					}
					if(menuItem != null){
						root.addMenuItem(menuItem);
					}else{
						root.addSubmenu(submenu);
					}
				}
			}
		}
		return root;
	}
	
	private void adicionarMenu(OpcionMenu opcionMenu, List<OpcionMenu> list, Submenu submenu)
			throws Exception {
		for (int i = 0; i < list.size(); i++) {
			OpcionMenu drOpcionResumen = list.get(i);
			
			if (opcionMenu.getIdOpcion().equals(drOpcionResumen.getIdOpcionPadre())) {
				if(isUltimoHijo(list, drOpcionResumen)){
					MenuItem menuItem = createMenuItem(drOpcionResumen);
					submenu.getChildren().add(menuItem);
				}else{
					Submenu drSubmenu = new Submenu();
					drSubmenu.setLabel(drOpcionResumen.getNomOpcion());
					submenu.getChildren().add(drSubmenu);
					adicionarMenu(drOpcionResumen, list, drSubmenu);
				}
			}
		}
	}
	
	private boolean isUltimoHijo(List<OpcionMenu> list, OpcionMenu opcionMenu){
		boolean ultimoHijo = true;
		for (int i = 0; i < list.size(); i++) {
			OpcionMenu ob = list.get(i);
			if (opcionMenu.getIdOpcion().equals(ob.getIdOpcionPadre())) {
				ultimoHijo = false;
				break;
			}
		}
		return ultimoHijo;
	}
	
	private MenuItem createMenuItem(OpcionMenu opcionMenu){
		MenuItem item = new MenuItem();
		
		item.setValue(opcionMenu.getNomOpcion());
		String url = opcionMenu.getFuncionUrl();
		if(url != null && url.trim().length() > 0){
			item.setUrl(url.trim());
		}else{
			item.setUrl(Constantes.SIMBOLO_NUMERAL);
		}
		
		return item;
	}
}
